首页 / 技术类 / 逆向 / 佳宜客户管理软件 v2.05 注册算法分析

佳宜客户管理软件 v2.05 注册算法分析

2008-06-03 00:40:00

这几天老想找个东西破破,无奈加密都太高明,我又太弱

下午逛 WZ,看到去年发的一个帖子(当时是发个破解混分数),后面有人求新版破解。 于是把新版下载下来研究

发现注册判断一点也没有变

MessageBoxA 设断点,随便输入注册码,断住后跳出 MessageBoxA 本身,然后再跳出一层函数,往上看,就找到了判断的地方:

1005ED03D  0F85 FE000000 jnz   005ED141

上次是直接把这个 jnz 改成 jmp 的 现在仍然这么做,还是有效,任意注册码可注册成功 这个软件判断注册成功的时候会把正确的注册信息写入注册表,所以下次再开原版也没关系。

本来想就这么搞,继续混一分的。后来想想这太没追求了,于是开始一句一句看。

具体分析如下(里面好多都没用,只是我当时不知道哪些有用哪些没用,一句句看下来了):

 1005ECF4C  55            push  ebp
 2005ECF4D  68 B2D15E00   push  005ED1B2
 3005ECF52  64:FF30       push  dword ptr fs:[eax]
 4005ECF55  64:8920       mov   dword ptr fs:[eax], esp
 5005ECF58  8D55 F0       lea   edx, dword ptr [ebp-10]     ; EDX="hNG"
 6005ECF5B  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=01660A70
 7005ECF5E  8B80 04030000 mov   eax, dword ptr [eax+304]    ; EAX=[EAX+304]=[01660D74]=01656380
 8005ECF64  E8 3F1BE6FF   call  0044EAA8
 9005ECF69  8B45 F0       mov   eax, dword ptr [ebp-10]     ; EAX=0163906C="abcd"
10005ECF6C  8D55 F4       lea   edx, dword ptr [ebp-C]      ; [ebp-C]=00000000
11005ECF6F  E8 18C8E1FF   call  0040978C                    ; 去除用户名首尾空格
12005ECF74  837D F4 00    cmp   dword ptr [ebp-C], 0        ; [ebp-C]=0163B2D0="abcd"
13005ECF78  75 22         jnz   short 005ECF9C
14005ECF7A  6A 00         push  0
15005ECF7C  68 C0D15E00   push  005ED1C0
16005ECF81  E8 2AFBFEFF   call  <jmp.&PunUnitLib.ShowMess>  ; 提示填写用户名称
17005ECF86  8B45 FC       mov   eax, dword ptr [ebp-4]
18005ECF89  8B80 04030000 mov   eax, dword ptr [eax+304]
19005ECF8F  8B10          mov   edx, dword ptr [eax]
20005ECF91  FF92 C0000000 call  dword ptr [edx+C0]
21005ECF97  E9 B1010000   jmp   005ED14D
22005ECF9C  8D55 E8       lea   edx, dword ptr [ebp-18]     ; EDX=0012F39C, [EDX]=00000000
23005ECF9F  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=01660A70
24005ECFA2  8B80 FC020000 mov   eax, dword ptr [eax+2FC]    ; EAX=[01660D6C]=01662F58, [EAX]=004331E8
25005ECFA8  E8 FB1AE6FF   call  0044EAA8                    ; 不知道在干嘛
26005ECFAD  8B45 E8       mov   eax, dword ptr [ebp-18]     ; EAX=0163B2D0="1234"
27005ECFB0  8D55 EC       lea   edx, dword ptr [ebp-14]     ; [ebp-14]=00000000
28005ECFB3  E8 D4C7E1FF   call  0040978C                    ; 去除注册码首尾空格
29005ECFB8  837D EC 00    cmp   dword ptr [ebp-14], 0       ; [ebp-14]=01646B4C="1234"
30005ECFBC  75 22         jnz   short 005ECFE0
31005ECFBE  6A 00         push  0
32005ECFC0  68 D4D15E00   push  005ED1D4
33005ECFC5  E8 E6FAFEFF   call  <jmp.&PunUnitLib.ShowMess>  ; 提示输入注册码
34005ECFCA  8B45 FC       mov   eax, dword ptr [ebp-4]
35005ECFCD  8B80 FC020000 mov   eax, dword ptr [eax+2FC]
36005ECFD3  8B10          mov   edx, dword ptr [eax]
37005ECFD5  FF92 C0000000 call  dword ptr [edx+C0]
38005ECFDB  E9 6D010000   jmp   005ED14D
39005ECFE0  A1 94A96300   mov   eax, dword ptr [63A994]     ; EAX=[0063A994]=00639D44
40005ECFE5  8B00          mov   eax, dword ptr [eax]        ; EAX=[00639D44]=005DCB44="6J9Y-K3H7"
41005ECFE7  E8 0080E1FF   call  00404FEC                    ; 不知道在干嘛
42005ECFEC  50            push  eax                         ; EAX=005DCB44="6J9Y-K3H7"
43005ECFED  8D55 E4       lea   edx, dword ptr [ebp-1C]     ; [ebp-1C]=00000000
44005ECFF0  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=01660A70
45005ECFF3  8B80 F4020000 mov   eax, dword ptr [eax+2F4]    ; EAX=[01660D64]=01662C98, [EAX]=004331E8
46005ECFF9  E8 AA1AE6FF   call  0044EAA8                    ; 不知道在干嘛
47005ECFFE  8B45 E4       mov   eax, dword ptr [ebp-1C]     ; EAX=[ebp-1C]=0165EC18="WD-WCARY0610755"
48005ED001  E8 E67FE1FF   call  00404FEC                    ; 不知道在干嘛
49005ED006  50            push  eax                         ; EAX=0165EC18="WD-WCARY0610755", 机器码
50005ED007  E8 D4FAFEFF   call  <jmp.&PunUnitLib.GetRegPass>; 算注册码
51005ED00C  8BD0          mov   edx, eax                    ; EDX=EAX=01512524="6J9Y-5353-K3H7-7303"
52005ED00E  8D45 F8       lea   eax, dword ptr [ebp-8]      ; [ebp-8]=[0012F3AC]=00000000
53005ED011  E8 167DE1FF   call  00404D2C                    ; [ebp-8]=0165EC34=正确注册码
54005ED016  8D55 DC       lea   edx, dword ptr [ebp-24]     ; [ebp-24]=00000000
55005ED019  8B45 FC       mov   eax, dword ptr [ebp-4]      ; EAX=[0012F3B0]=01660A70
56005ED01C  8B80 FC020000 mov   eax, dword ptr [eax+2FC]    ; EAX=[01660D6C]=01662F58, [EAX]=004331T8
57005ED022  E8 811AE6FF   call  0044EAA8                    ; 不知道在干嘛
58005ED027  8B45 DC       mov   eax, dword ptr [ebp-24]     ; EAX="1234", 错误注册码
59005ED02A  8D55 E0       lea   edx, dword ptr [ebp-20]     ; [ebp-20]=[0012F394]=00000000
60005ED02D  E8 5AC7E1FF   call  0040978C                    ; 复制字符串?
61005ED032  8B45 E0       mov   eax, dword ptr [ebp-20]     ; EAX=[ebp-20]="1234", 错误注册码
62005ED035  8B55 F8       mov   edx, dword ptr [ebp-8]      ; EDX=0165EC34=正确注册码
63005ED038  E8 FB7EE1FF   call  00404F38                    ; 比较
64005ED03D  0F85 FE000000 jnz   005ED141                    ; 不同则跳 

上面是一段,大体情况已经清楚,注册码中的第一段和第三段是常量,第二段和第四段则是算出来的

下面看算注册码的函数 PunUnitLib.GetRegPass

  1007D9024  55            push  ebp
  2007D9025  8BEC          mov   ebp, esp
  3007D9027  B9 06000000   mov   ecx, 6                    ; 循环 6 次
  4007D902C  6A 00         push  0
  5007D902E  6A 00         push  0
  6007D9030  49            dec   ecx
  7007D9031  75 F9         jnz   short 007D902C            ; 循环尾,一共 PUSH 了 12 个 0
  8007D9033  53            push  ebx                       ; EBX=01628E04="hNG"
  9007D9034  56            push  esi                       ; ESI=004773E0
 10007D9035  33C0          xor   eax, eax
 11007D9037  55            push  ebp
 12007D9038  68 F2917D00   push  007D91F2
 13007D903D  64:FF30       push  dword ptr fs:[eax]
 14007D9040  64:8920       mov   dword ptr fs:[eax], esp
 15007D9043  8D45 EC       lea   eax, dword ptr [ebp-14]
 16007D9046  E8 65B5F8FF   call  007645B0
 17007D904B  8D45 F0       lea   eax, dword ptr [ebp-10]   ; [ebp-10]=[0012F360]=00000000
 18007D904E  8B55 08       mov   edx, dword ptr [ebp+8]    ; EDX=[0012F348]=01512400="WD-WCARY0610755"
 19007D9051  E8 4AB7F8FF   call  007647A0
 20007D9056  8B45 F0       mov   eax, dword ptr [ebp-10]   ; [ebp-10]=[0012F348]=01512400="WD-WCARY0610755"
 21007D9059  E8 0AB8F8FF   call  00764868                  ; 求机器码长度
 22007D905E  8BF0          mov   esi, eax                  ; ESI=EAX=0000000F
 23007D9060  85F6          test  esi, esi
 24007D9062  7E 26         jle   short 007D908A            ; 机器码为空?
 25007D9064  BB 01000000   mov   ebx, 1                    ; 记录循环次数(N),下行开始循环
 26007D9069  8D4D E8       lea   ecx, dword ptr [ebp-18]   ; [ebp-18]=[0012F340]=00000000
 27007D906C  8B45 F0       mov   eax, dword ptr [ebp-10]   ; EAX="WD-WCARY0610755"
 28007D906F  0FB64418 FF   movzx eax, byte ptr [eax+ebx-1] ; EAX=第N个字符='W'=57h
 29007D9074  33D2          xor   edx, edx
 30007D9076  E8 F905F9FF   call  00769674                  ; 数值转字符(十六进制)
 31007D907B  8B55 E8       mov   edx, dword ptr [ebp-18]   ; EDX=[ebp-18]=[0012F340]=0051241C="57"
 32007D907E  8D45 FC       lea   eax, dword ptr [ebp-4]    ; [ebp-4]=[0012F354]=00000000
 33007D9081  E8 EAB7F8FF   call  00764870                  ; [ebp-4]=0041241C="57"
 34007D9086  43            inc   ebx
 35007D9087  4E            dec   esi
 36007D9088  75 DF         jnz   short 007D9069            ; 循环尾
 37007D908A  8B45 FC       mov   eax, dword ptr [ebp-4]    ; EAX=[ebp-4]=0151243C="57442D574341525930363130373535"
 38                                                        ; 原来刚才的循环是把每一个字符的 ASCII 码拼起来
 39007D908D  E8 D6B7F8FF   call  00764868                  ; 求字符串长度
 40007D9092  8BF0          mov   esi, eax                  ; ESI=EAX=0000001E
 41007D9094  85F6          test  esi, esi
 42007D9096  7E 2C         jle   short 007D90C4            ; 又来判断字符串为空?刚才不是判断过了。。
 43007D9098  BB 01000000   mov   ebx, 1                    ; 记录循环次数(N),下行开始循环
 44007D909D  8B45 FC       mov   eax, dword ptr [ebp-4]    ; EAX=[ebp-4]=0151243C="57442D574341525930363130373535"
 45007D90A0  E8 C3B7F8FF   call  00764868                  ; 求字符串长度, EAX=0000001E
 46007D90A5  2BC3          sub   eax, ebx                  ; EAX=EAX-N=1D(N=1)
 47007D90A7  8B55 FC       mov   edx, dword ptr [ebp-4]    ; EDX=[ebp-4]=0151243C="57442D574341525930363130373535"
 48007D90AA  8A1402        mov   dl, byte ptr [edx+eax]    ; DL=倒数第N个字符 1st:DL='5'=35h, 2nd:DL='3'=33h
 49007D90AD  8D45 E4       lea   eax, dword ptr [ebp-1C]   ; [ebp-1C]=[0012F33C]=00000000
 50007D90B0  E8 DBB6F8FF   call  00764790
 51007D90B5  8B55 E4       mov   edx, dword ptr [ebp-1C]   ; 1st: EDX=[ebp-1C]=[0012F33C]=0151242C, [EDX]=00000035
 52                                                        ; 2nd: EDX=[ebp-1C]=[0012F33C]=01512468, [EDX]=00000033
 53007D90B8  8D45 F8       lea   eax, dword ptr [ebp-8]    ; 1st: [ebp-8]=[0012F350]=00000000
 54                                                        ; 2nd: [ebp-8]=[0012F350]=0151242C="5"
 55007D90BB  E8 B0B7F8FF   call  00764870                  ; 1st: [ebp-8]=[0012F350]=0151242C="5"
 56                                                        ; 2nd: [ebp-8]=[0012F350]=0151242C="53"
 57                                                        ; 3st: [ebp-8]=[0012F350]=0151242C="535"
 58                                                        ; 4th: [ebp-8]=[0012F350]=01512478="5353"
 59                                                        ; 5th: [ebp-8]=[0012F350]=01512478="53537"
 60                                                        ; ……
 61007D90C0  43            inc   ebx
 62007D90C1  4E            dec   esi
 63007D90C2  75 D9         jnz   short 007D909D            ; 循环尾
 64                                                        ; [ebp-8]=01512478="535373031363039525143475D24475"
 65                                                        ; 刚才那个循环把这字符串倒了一下
 66007D90C4  8D45 FC       lea   eax, dword ptr [ebp-4]    ; EAX=[ebp-4]=0151243C="57442D574341525930363130373535"
 67007D90C7  50            push  eax                       ; 00764AC0 的参数四,buffer
 68007D90C8  B9 04000000   mov   ecx, 4                    ; 参数三,要取的字符数
 69007D90CD  BA 01000000   mov   edx, 1                    ; 参数二,从第几位开始取
 70007D90D2  8B45 F8       mov   eax, dword ptr [ebp-8]    ; 参数一,要取子串的字符串
 71                                                        ; EAX=[ebp-8]=01512478="535373031363039525143475D24475"
 72007D90D5  E8 E6B9F8FF   call  00764AC0                  ; 取子串。EAX=0012F354, [EAX]=015124A4="5353"
 73007D90DA  8D45 F8       lea   eax, dword ptr [ebp-8]
 74007D90DD  50            push  eax
 75007D90DE  B9 04000000   mov   ecx, 4                    ; 取 4 位
 76007D90E3  BA 05000000   mov   edx, 5                    ; 从第 5 位开始取
 77007D90E8  8B45 F8       mov   eax, dword ptr [ebp-8]    ; 还是那串字符串
 78007D90EB  E8 D0B9F8FF   call  00764AC0                  ; 取子串。EAX=0012F350, [EAX]=015124B8="7303"
 79007D90F0  8B45 FC       mov   eax, dword ptr [ebp-4]    ; EAX="5353"
 80007D90F3  E8 70B7F8FF   call  00764868                  ; 求字符串长度
 81007D90F8  83F8 04       cmp   eax, 4
 82007D90FB  7D 2F         jge   short 007D912C            ; 长度为 4, 跳到 007D912C。下面是长度小于 4 的处理
 83007D90FD  8B45 FC       mov   eax, dword ptr [ebp-4]    ; 假设机器码只有一个"W",EAX="75"
 84007D9100  E8 63B7F8FF   call  00764868                  ; 求长
 85007D9105  8BD8          mov   ebx, eax                  ; EBX=EAX=2
 86007D9107  83FB 03       cmp   ebx, 3
 87007D910A  7F 20         jg    short 007D912C            ; 大于 3,仍然跳到 007D912C。这个判断似乎又是多此一举?
 88007D910C  8D4D E0       lea   ecx, dword ptr [ebp-20]   ; [ebp-20]=[0012F338]=00000000
 89007D910F  8BC3          mov   eax, ebx                  ; 1st: EAX=EBX=00000002
 90                                                        ; 2nd: EAX=3
 91007D9111  C1E0 02       shl   eax, 2                    ; 1st: EAX=EAX*4=00000008
 92                                                        ; 2nd: EAX=EAX*4=C
 93007D9114  33D2          xor   edx, edx
 94007D9116  E8 5905F9FF   call  00769674                  ; 1st: EAX="8"
 95                                                        ; 2nd: EAX="C"
 96007D911B  8B55 E0       mov   edx, dword ptr [ebp-20]   ; EDX=[ebp-20]=[0012F338]=015124CC, EDX=59390043
 97007D911E  8D45 FC       lea   eax, dword ptr [ebp-4]    ; 1st: [ebp-4]=015124A4="758"
 98                                                        ; 2nd: [ebp-4]=015124A4="758C"
 99007D9121  E8 4AB7F8FF   call  00764870
100007D9126  43            inc   ebx
101007D9127  83FB 04       cmp   ebx, 4                    ; 没有补到 4 个则继续
102007D912A  75 E0         jnz   short 007D910C
103007D912C  8B45 F8       mov   eax, dword ptr [ebp-8]
104007D912F  E8 34B7F8FF   call  00764868
105007D9134  83F8 04       cmp   eax, 4
106007D9137  7D 2F         jge   short 007D9168
107007D9139  8B45 F8       mov   eax, dword ptr [ebp-8]
108007D913C  E8 27B7F8FF   call  00764868
109007D9141  8BD8          mov   ebx, eax
110007D9143  83FB 03       cmp   ebx, 3
111007D9146  7F 20         jg    short 007D9168
112007D9148  8D4D DC       lea   ecx, dword ptr [ebp-24]
113007D914B  8BC3          mov   eax, ebx
114007D914D  C1E0 02       shl   eax, 2
115007D9150  33D2          xor   edx, edx
116007D9152  E8 1D05F9FF   call  00769674
117007D9157  8B55 DC       mov   edx, dword ptr [ebp-24]
118007D915A  8D45 F8       lea   eax, dword ptr [ebp-8]    ; 这里缺位也跟上面一样补,补为 048C
119                                                        ; 不管原来几位最后都是 048C, *48C, **8C, ***C, ****
120007D915D  E8 0EB7F8FF   call  00764870
121007D9162  43            inc   ebx
122007D9163  83FB 04       cmp   ebx, 4
123007D9166  75 E0         jnz   short 007D9148
124007D9168  8D45 D8       lea   eax, dword ptr [ebp-28]   ; [ebp-28]=[0012F330]=00000000
125007D916B  8B55 0C       mov   edx, dword ptr [ebp+C]    ; EDX=[0012F364]=005DCB44="6J9Y-K3H7"
126007D916E  E8 2DB6F8FF   call  007647A0
127007D9173  8B45 D8       mov   eax, dword ptr [ebp-28]   ; EAX=[ebp-28]=[0012F330]=01512488="6J9Y-K3H7"
128007D9176  8D55 F4       lea   edx, dword ptr [ebp-C]    ; [ebp-C]=[0012F34C]=00000000
129007D9179  E8 DE03F9FF   call  0076955C                  ; [ebp-C]=[0012F34C]=015124A0="6J9Y-K3H7"
130007D917E  8D45 D4       lea   eax, dword ptr [ebp-2C]   ; [ebp-2C]=[0012F32C]=00000000
131007D9181  50            push  eax
132007D9182  B9 04000000   mov   ecx, 4
133007D9187  BA 01000000   mov   edx, 1
134007D918C  8B45 F4       mov   eax, dword ptr [ebp-C]
135007D918F  E8 2CB9F8FF   call  00764AC0                  ; [ebp-2C]=[0012F32C]=015124B8="6J9Y"
136007D9194  FF75 D4       push  dword ptr [ebp-2C]
137007D9197  68 0C927D00   push  007D920C
138007D919C  FF75 FC       push  dword ptr [ebp-4]
139007D919F  8D45 D0       lea   eax, dword ptr [ebp-30]
140007D91A2  50            push  eax
141007D91A3  B9 05000000   mov   ecx, 5
142007D91A8  BA 05000000   mov   edx, 5
143007D91AD  8B45 F4       mov   eax, dword ptr [ebp-C]
144007D91B0  E8 0BB9F8FF   call  00764AC0
145007D91B5  FF75 D0       push  dword ptr [ebp-30]        ; [ebp-30]=[0012F328]=015124CC="-K3H7"
146007D91B8  68 0C927D00   push  007D920C
147007D91BD  FF75 F8       push  dword ptr [ebp-8]
148007D91C0  8D45 EC       lea   eax, dword ptr [ebp-14]
149007D91C3  BA 06000000   mov   edx, 6
150007D91C8  E8 5BB7F8FF   call  00764928                  ; 这里就是拼接起来,懒得仔细看了
151                                                        ; 最后是 6J9Y-5353-K3H7-7303
152007D91CD  8B45 EC       mov   eax, dword ptr [ebp-14]
153007D91D0  E8 8BB8F8FF   call  00764A60
154007D91D5  8BD8          mov   ebx, eax
155007D91D7  33C0          xor   eax, eax
156007D91D9  5A            pop   edx
157007D91DA  59            pop   ecx
158007D91DB  59            pop   ecx
159007D91DC  64:8910       mov   dword ptr fs:[eax], edx
160007D91DF  68 F9917D00   push  007D91F9
161007D91E4  8D45 D0       lea   eax, dword ptr [ebp-30]
162007D91E7  BA 0C000000   mov   edx, 0C
163007D91EC  E8 E3B3F8FF   call  007645D4
164007D91F1  C3            retn
165007D91F2  E9 1DADF8FF   jmp   00763F14
166007D91F7  EB EB         jmp   short 007D91E4
167007D91F9  8BC3          mov   eax, ebx
168007D91FB  5E            pop   esi
169007D91FC  5B            pop   ebx
170007D91FD  8BE5          mov   esp, ebp
171007D91FF  5D            pop   ebp
172007D9200  C2 0800       retn  8 

哈哈,终于熬出头了,再写个注册机(仅供学习研究,请下载后24小时内删除)

第一次完整地把算法分析出来,真兴奋~


首发:https://blog.csdn.net/cnStreamlet/article/details/2505288



NoteIsSite/0.4